#pragma once
#include <windows.h>
#include <tchar.h>
#include <vector>
#include "glew/glew.h"
#include "glm/glm.hpp"
#include "SDL2/SDL.h"
#include "BlueprintScriptLibrary/BaseInc.h"
#include "BlueprintScriptLibrary/Pin.h"
#include "BlueprintScriptLibrary/Reflections.h"
#include "BlueprintScriptLibrary/RegistAction.h"
#include "BlueprintScriptLibrary/Var.h"
#include <share.h>
#include <functional>
#include <freetype/ft2build.h>
#include "freetype/freetype/freetype.h"
#include "tinyxml/tinyxml.h"
#pragma comment(lib,"opengl32.lib")
#pragma comment(lib,"glu32.lib")
#pragma comment(lib,"glew32s.lib")
#pragma  comment(lib,"SDL2.lib")
#pragma  comment(lib,"SDL2main.lib")
#pragma  comment(lib,"BlueprintScriptLibrary.lib")
#pragma comment(lib,"freetypes.lib")
#pragma comment(lib,"base.lib")

using namespace BlueprintScriptLibrary;
template<class T>
struct Vec2 :public BlueprintScriptLibrary::Object
{
	T x;
	T y;
	Vec2() {}
	Class* GetClass()
	{
		Array<NativeMembers>  arrMembers(2);
		arrMembers.data[0]->Init("x", offsetof(Vec2, x), sizeof(x), T::GetType());
		arrMembers.data[1]->Init("y", offsetof(Vec2, y), sizeof(y), T::GetType());
		//v.push_back(BlueprintScriptLibrary::NativeMembers("vbia", offsetof(MyClass, vbia), "int"));
		arrMembers.bGlobalScope = true;
		Array<MethodPin>  arrMethods(1, false);
		return	BlueprintScriptLibrary::Class::BuildClassFromArray("vec2", arrMembers, arrMethods);
	}
	Vec2(T xx, T yy)
	{
		x = xx;
		y = yy;
	}
	Vec2(const glm::vec2& v) {
		this->x.val = v.x;
		this->y.val = v.y;
	}
	Vec2 operator +=(const Vec2& r)
	{
		x += r.x;
		y += r.y;
		return *this;
	}
	Vec2 operator =(const Vec2& r)
	{
		this->x = r.x;
		this->y = r.y;
		return *this;
	}
	Vec2 operator =(const glm::vec2& r)
	{
		/*this->x = (T)r.x;
		this->y = (T)r.y;*/
		return *this;
	}
	//std::string ToString()
	//{
	//	std::string src = "";
	//	src += "("+x.ToString() + "," + y.ToString() + ")";
	//	return x.ToString();
	//}
};
template<class T>
struct Vec4 :public BlueprintScriptLibrary::Object
{
	T x;
	T y;
	T z;
	T w;
	Vec4() {}
	Vec4(const glm::vec4& v){
		this->x = (T)v.x;
		this->y = (T)v.y;
		this->z = (T)v.z;
		this->w = (T)v.w;
	}
	Class* GetClass()
	{
		Array<NativeMembers>  arrMembers(4);
		arrMembers.data[0]->Init("x", offsetof(Vec4, x), sizeof(x), T::GetType());
		arrMembers.data[1]->Init("y", offsetof(Vec4, y), sizeof(y), T::GetType());
		arrMembers.data[1]->Init("z", offsetof(Vec4, z), sizeof(z), T::GetType());
		arrMembers.data[1]->Init("w", offsetof(Vec4, w), sizeof(w), T::GetType());
		//v.push_back(BlueprintScriptLibrary::NativeMembers("vbia", offsetof(MyClass, vbia), "int"));
		arrMembers.bGlobalScope = true;
		Array<MethodPin>  arrMethods(4, false);
		return	BlueprintScriptLibrary::Class::BuildClassFromArray("vec4", arrMembers, arrMethods);
	}
	Vec4 operator +=(Vec4 r)
	{
		x += r.x;
		y += r.y;
		z += r.z;
		w += r.w;
		return *this;
	}
	Vec4 operator =(const glm::vec4& r)
	{
		/*this->x = (T)r.x;
		this->y = (T)r.y;
		this->z = (T)r.z;
		this->w = (T)r.w;*/
		return *this;
	}
};

typedef Vec2<int> vec2i;
typedef Vec2<float> vec2f;
typedef Vec4<int> vec4i;
typedef Vec4<float> vec4f;
typedef Vec2<VarBaseFloat> Vec2vbf;
RegisterBlueprintClass(Vec2vbf)
typedef Vec2<VarBaseInt> Vec2vbi;
RegisterBlueprintClass(Vec2vbi)
typedef Vec4<VarBaseFloat> Vec4vbf;
RegisterBlueprintClass(Vec4vbf)
typedef Vec4<VarBaseInt> Vec4vbi;
RegisterBlueprintClass(Vec4vbi)
//RegisterBlueprintClass(vec2f)
//RegisterBlueprintClass(vec4i)
//RegisterBlueprintClass(vec4f)







